﻿using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Controls;
using System.Threading;

namespace RaisingStudio.SmallProgram.Library
{
    [SmallProgramType]
    public static class Controls
    {
        private static Dictionary<string, Point> _positionMap = new Dictionary<string, Point>();

        private static Primitive _lastClickedButton;
        public static Primitive LastClickedButton
        {
            get
            {
                return _lastClickedButton;
            }
        }

        private static SmallProgramCallback _buttonClicked;
        public static event SmallProgramCallback ButtonClicked
        {
            add
            {
                _buttonClicked = null;
                _buttonClicked += value;
            }
            remove
            {
                _buttonClicked -= value;
            }
        }
        private static void OnButtonClicked(object sender, RoutedEventArgs e)
        {
            Button button = sender as Button;
            string name = button.Name;
            if (GraphicsWindow._objectsMap.ContainsKey(name))
            {
                _lastClickedButton = name;
                SmallProgramCallback buttonClicked = _buttonClicked;
                if (buttonClicked != null)
                {
                    buttonClicked();
                }
            }
        }

        private static Primitive _lastTypedTextBox;
        public static Primitive LastTypedTextBox
        {
            get
            {
                return _lastTypedTextBox;
            }
        }

        private static SmallProgramCallback _textTyped;
        public static event SmallProgramCallback TextTyped
        {
            add
            {
                _textTyped = null;
                _textTyped += value;
            }
            remove
            {
                _textTyped -= value;
            }
        }
        private static void OnTextChanged(object sender, EventArgs e)
        {
            TextBox textBox = sender as TextBox;
            string name = textBox.Name;
            if (GraphicsWindow._objectsMap.ContainsKey(name))
            {
                _lastTypedTextBox = name;
                SmallProgramCallback textTyped = _textTyped;
                if (textTyped != null)
                {
                    textTyped();
                }
            }
        }
        

        public static Primitive AddButton(Primitive caption, Primitive left, Primitive top)
        {
            string name = Shapes.GenerateNewName("Button");
            GraphicsWindow.Invoke(delegate
            {
                Button button = new Button
                {
                    Content = caption,
                    Padding = new Thickness(4.0)
                };
                Canvas.SetLeft(button, (double)left);
                Canvas.SetTop(button, (double)top);
                button.Click += new RoutedEventHandler(Controls.OnButtonClicked);
                GraphicsWindow.AddControl(name, button);
            });
            return name;
        }
        public static Primitive AddTextBox(Primitive left, Primitive top)
        {
            string name = Shapes.GenerateNewName("TextBox");
            GraphicsWindow.Invoke(delegate
            {
                TextBox textBox = new TextBox
                {
                    Width = 160.0,
                    Padding = new Thickness(2.0)
                };
                Canvas.SetLeft(textBox, (double)left);
                Canvas.SetTop(textBox, (double)top);
                textBox.TextChanged += new TextChangedEventHandler(Controls.OnTextChanged);
                GraphicsWindow.AddControl(name, textBox);
            });
            return name;
        }
        public static Primitive AddMultiLineTextBox(Primitive left, Primitive top)
        {
            string name = Shapes.GenerateNewName("TextBox");
            GraphicsWindow.Invoke(delegate
            {
                TextBox textBox = new TextBox
                {
                    AcceptsReturn = true,
                    Width = 200.0,
                    Height = 80.0,
                    HorizontalScrollBarVisibility = ScrollBarVisibility.Auto,
                    VerticalScrollBarVisibility = ScrollBarVisibility.Auto,
                    Padding = new Thickness(2.0)
                };
                Canvas.SetLeft(textBox, (double)left);
                Canvas.SetTop(textBox, (double)top);
                textBox.TextChanged += new TextChangedEventHandler(Controls.OnTextChanged);
                GraphicsWindow.AddControl(name, textBox);
            });
            return name;
        }

        public static void Remove(Primitive controlName)
        {
            UIElement element;
            if (GraphicsWindow._objectsMap.TryGetValue(controlName, out element))
            {
                Button button = element as Button;
                if (button != null)
                {
                    button.Click -= new RoutedEventHandler(Controls.OnButtonClicked);
                }
                GraphicsWindow.RemoveShape(controlName);
            }
        }

        public static Primitive GetButtonCaption(Primitive buttonName)
        {
            UIElement element;
            if (!GraphicsWindow._objectsMap.TryGetValue(buttonName, out element))
            {
                return "";
            }
            Button button = element as Button;
            if (button == null)
            {
                return "";
            }
            return (Primitive)GraphicsWindow.InvokeWithReturn(() => button.Content.ToString());
        }
        public static void SetButtonCaption(Primitive buttonName, Primitive caption)
        {
            UIElement element;
            if (GraphicsWindow._objectsMap.TryGetValue(buttonName, out element))
            {
                Button button = element as Button;
                if (button != null)
                {
                    GraphicsWindow.BeginInvoke(delegate
                    {
                        button.Content = caption;
                    });
                }
            }
        }

        public static Primitive GetTextBoxText(Primitive textBoxName)
        {
            UIElement element;
            if (!GraphicsWindow._objectsMap.TryGetValue(textBoxName, out element))
            {
                return "";
            }
            TextBox textBox = element as TextBox;
            if (textBox == null)
            {
                return "";
            }
            return (Primitive)GraphicsWindow.InvokeWithReturn(() => textBox.Text);
        }
        public static void SetTextBoxText(Primitive textBoxName, Primitive text)
        {
            UIElement element;
            if (GraphicsWindow._objectsMap.TryGetValue(textBoxName, out element))
            {
                TextBox textBox = element as TextBox;
                if (textBox != null)
                {
                    GraphicsWindow.BeginInvoke(delegate
                    {
                        textBox.Text = (string)text;
                    });
                }
            }
        }

        public static void ShowControl(Primitive controlName)
        {
            UIElement element;
            if (GraphicsWindow._objectsMap.TryGetValue(controlName, out element))
            {
                GraphicsWindow.Invoke(delegate
                {
                    element.Visibility = Visibility.Visible;
                });
            }
        }
        public static void HideControl(Primitive controlName)
        {
            UIElement element;
            if (GraphicsWindow._objectsMap.TryGetValue(controlName, out element))
            {
                GraphicsWindow.Invoke(delegate
                {
                    element.Visibility = Visibility.Collapsed;
                });
            }
        }

        public static void SetSize(Primitive control, Primitive width, Primitive height)
        {
            UIElement element;
            if (GraphicsWindow._objectsMap.TryGetValue(control, out element))
            {
                FrameworkElement frameworkElement = element as FrameworkElement;
                if (element != null)
                {
                    GraphicsWindow.BeginInvoke(delegate
                    {
                        frameworkElement.Width = (double)width;
                        frameworkElement.Height = (double)height;
                    });
                }
            }
        }
        public static void Move(Primitive control, Primitive x, Primitive y)
        {
            UIElement element;
            if (GraphicsWindow._objectsMap.TryGetValue(control, out element))
            {
                _positionMap[(string)control] = new Point((double)x, (double)y);
                GraphicsWindow.BeginInvoke(delegate
                {
                    element.BeginAnimation(Canvas.LeftProperty, null);
                    element.BeginAnimation(Canvas.TopProperty, null);
                    Canvas.SetLeft(element, (double)x);
                    Canvas.SetTop(element, (double)y);
                });
            }
        }
    }
}

